//
//  HQSearchManager.m
//  o_amap
//
//  Created by Q神 on 2021/4/6.
//

#import "HQSearchManager.h"
/// 搜索
#import <AMapSearchKit/AMapSearchKit.h>
#import "HQMapTools.h"

#import "MJExtension.h"
#import "SearchPoiSearchQueryModel.h"
#import "SearchPoiResultModel.h"
#import "SearchRoutePoiQueryModel.h"
#import "SearchRoutePlanParamModel.h"
#import "SearchDistanceParamsModel.h"
#import "SearchReGeocodeResultModel.h"
#import "SearchInputTipsOptionsModel.h"
#import "SearchGeocodeOptionsModel.h"
#import "SearchReGeocodeOptionsModel.h"
#import "SearchInputTipsResultModel.h"
#import "SearchGeocodeResultModel.h"


@interface HQSearchManager() <AMapSearchDelegate>

@property (nonatomic, strong) FlutterResult flutterResult;

@property (nonatomic, strong) AMapSearchAPI *searchAPI;

@property (nonatomic, strong) HQMapTools * mapTools;

@end

@implementation HQSearchManager

+ (instancetype)shareInstance {
    static dispatch_once_t onceToken;
    static HQSearchManager * manager = nil;
    dispatch_once(&onceToken, ^{
        manager = [[HQSearchManager alloc] init];
    });
    return manager;
}

#pragma mark -- 插件方法

- (void)searchWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar withMapPlugin:(NSObject<FlutterPlugin> * _Nonnull)mapPlugin {

    FlutterMethodChannel *searchChannel = [FlutterMethodChannel methodChannelWithName:@"com.p595263720.zit/search" binaryMessenger:[registrar messenger]];
    [registrar addMethodCallDelegate:mapPlugin channel:searchChannel];
}

- (void)searchMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {

    self.flutterResult = result;

    if([@"searchPoi" isEqualToString:call.method]) {
        /// 搜索poi
        [self searchPoi:call];

    } else if([@"searchPoiBound" isEqualToString:call.method]) {
        /// 周边搜索
        NSLog(@"searchPoiBound=====%@", call.arguments);
        [self searchPoiBound:call];

    } else if([@"searchReGeocode" isEqualToString:call.method]) {
        /// 逆地理编码
        [self searchReGeocode:call];

    } else if([@"inputTips" isEqualToString:call.method]) {
        /// input关键字搜索
        [self inputTips:call];

    } else if([@"searchGeocode" isEqualToString:call.method]) {
        /// 地址转坐标
        [self searchGeocode:call];
        
    } else if([@"searchPoiPolygon" isEqualToString:call.method]) {
        /// 多边形搜索
        [self searchPoiPolygon:call];
        
    } else if([@"searchPoiId" isEqualToString:call.method]) {
        /// 按id搜索
        [self searchPoiId:call];
        
    } else if([@"searchRoutePoiLine" isEqualToString:call.method]) {
        /// 道路沿途直线检索POI
        [self searchRoutePoiLine:call];
        
    } else if([@"searchRoutePoiPolygon" isEqualToString:call.method]) {
        /// 道路沿途多边形检索POI
        [self searchRoutePoiPolygon:call];
        
    } else if([@"calculateDriveRoute" isEqualToString:call.method]) {
        /// 计算驾驶路线
        [self calculateDriveRoute:call];
        
    } else if([@"distanceSearch" isEqualToString:call.method]) {
        /// 距离测量
        [self distanceSearch:call];
        
    } else if([@"searchBusStation" isEqualToString:call.method]) {
        /// 公交站点查询
        [self searchBusStation:call];
        
    } else if([@"searchBusLine" isEqualToString:call.method]) {
        /// 公交线路查询
        [self searchBusLine:call];
        
    }
}

#pragma mark -- 事件处理

- (void)searchPoi:(FlutterMethodCall *)call {
    if (call.arguments) {
        NSString *query = [self.mapTools isBlankString:call.arguments[@"query"]] ? call.arguments[@"query"] : @"{}";
        [self.searchAPI AMapPOIKeywordsSearch:[SearchPoiSearchQueryModel initSearchKeywordsQuery:query]];
    }
}

- (void)searchPoiBound:(FlutterMethodCall *)call {
    if (call.arguments) {
        NSString *query = [self.mapTools isBlankString:call.arguments[@"query"]] ? call.arguments[@"query"] : @"{}";
        [self.searchAPI AMapPOIAroundSearch:[SearchPoiSearchQueryModel initSearchAroundQuery:query]];
    }
}

- (void)inputTips:(FlutterMethodCall *)call {
    if (call.arguments) {
        SearchInputTipsOptionsModel *model = [SearchInputTipsOptionsModel mj_objectWithKeyValues:call.arguments];
        [self.searchAPI AMapInputTipsSearch:[model inputTips]];
    }
}

- (void)searchGeocode:(FlutterMethodCall *)call {
    if (call.arguments) {
        SearchGeocodeOptionsModel *model = [SearchGeocodeOptionsModel mj_objectWithKeyValues:call.arguments];
        [self.searchAPI AMapGeocodeSearch:[model searchGeocode]];
    }
}

- (void)searchReGeocode:(FlutterMethodCall *)call {
    if (call.arguments) {
        SearchReGeocodeOptionsModel *model = [SearchReGeocodeOptionsModel mj_objectWithKeyValues:call.arguments];
        [self.searchAPI AMapReGoecodeSearch:[model searchReGeocode]];
    }
}

- (void)searchPoiPolygon:(FlutterMethodCall *)call {
    if (call.arguments) {
        NSString *query = call.arguments[@"query"] ? call.arguments[@"query"] : @"{}";
        [self.searchAPI AMapPOIPolygonSearch:[SearchPoiSearchQueryModel initSearchPoiPolygonQuery:query]];
    }
}

- (void)searchPoiId:(FlutterMethodCall *)call {
    if (call.arguments) {
        AMapPOIIDSearchRequest *request = [[AMapPOIIDSearchRequest alloc] init];
        request.uid                 = call.arguments[@"id"];
        [self.searchAPI AMapPOIIDSearch:request];
    }
}

- (void)searchRoutePoiLine:(FlutterMethodCall *)call {
    if (call.arguments) {
        NSString *query = call.arguments;
        [self.searchAPI AMapRoutePOISearch:[SearchRoutePoiQueryModel searchRoutePoiLine:query]];
    }
}

- (void)searchRoutePoiPolygon:(FlutterMethodCall *)call {}

- (void)calculateDriveRoute:(FlutterMethodCall *)call {
    if (call.arguments) {
        NSString *query = [self.mapTools isBlankString:call.arguments[@"query"]] ? call.arguments[@"query"] : @"{}";
        [self.searchAPI AMapDrivingRouteSearch:[SearchRoutePlanParamModel calculateDriveRoute:query]];
    }
}

- (void)distanceSearch:(FlutterMethodCall *)call {
    if (call.arguments) {
        NSString *query = call.arguments;
        [self.searchAPI AMapDistanceSearch:[SearchDistanceParamsModel distanceSearch:query]];
    }
}

- (void)searchBusStation:(FlutterMethodCall *)call {
    if (call.arguments) {
        AMapBusStopSearchRequest *stop = [[AMapBusStopSearchRequest alloc] init];
        stop.keywords = call.arguments[@"stationName"];
        stop.city     = call.arguments[@"city"];
        [self.searchAPI AMapBusStopSearch:stop];
    }
}

- (void)searchBusLine:(FlutterMethodCall *)call {
    if (call.arguments) {
        AMapBusLineNameSearchRequest *line = [[AMapBusLineNameSearchRequest alloc] init];
        line.keywords           = call.arguments[@"stationName"];
        line.city               = call.arguments[@"city"];
        line.requireExtension   = YES;
        [self.searchAPI AMapBusLineNameSearch:line];
    }
}

#pragma mark -- 搜索回调

/* POI 搜索回调. */
- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response {
    
    if (response.pois.count == 0) return;
    /// 解析response获取POI信息
    SearchPoiResultModel *resultModel = [SearchPoiResultModel createPoiResultModelWithResponse:response];
    NSString *jsonString = [self.mapTools hq_jsonStringPrettyPrintedFormatForDictionary:[resultModel mj_keyValues]];
    NSLog(@"搜索结果 == %@", jsonString);
    self.flutterResult(jsonString);
}

/* 输入提示回调. */
- (void)onInputTipsSearchDone:(AMapInputTipsSearchRequest *)request response:(AMapInputTipsSearchResponse *)response {
    
    /// 解析response获取提示词
    if (response.tips.count == 0) return;
    SearchInputTipsResultModel *model = [SearchInputTipsResultModel createInputTipsResultModelWithResponse:response];
    NSString *jsonString = [self.mapTools hq_jsonStringPrettyPrintedFormatForDictionary:[model mj_keyValues]];
    self.flutterResult(jsonString);
}

/* 地址转坐标. */
- (void)onGeocodeSearchDone:(AMapGeocodeSearchRequest *)request response:(AMapGeocodeSearchResponse *)response {
    
    /// 解析response获取POI信息
    if (response.geocodes.count == 0) return;
    SearchGeocodeResultModel *model = [SearchGeocodeResultModel createGeocodeResultModelWithResponse:response];
    NSString *jsonString = [self.mapTools hq_jsonStringPrettyPrintedFormatForDictionary:[model mj_keyValues]];
    self.flutterResult(jsonString);
}

/* 逆地理编码. */
- (void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response {
    
    /// 解析response获取POI信息
    if (response.regeocode == nil) return;
    SearchReGeocodeResultModel *reGeocodeResultModel = [SearchReGeocodeResultModel createSearchReGeocodeResultModelWithResponse:response];
    NSString *jsonString = [self.mapTools hq_jsonStringPrettyPrintedFormatForDictionary:[reGeocodeResultModel mj_keyValues]];
    self.flutterResult(jsonString);
}

/* 沿途搜索回调. */
- (void)onRoutePOISearchDone:(AMapRoutePOISearchRequest *)request response:(AMapRoutePOISearchResponse *)response {
    
    if (response.pois.count == 0) return;
   /// 解析response获取POI信息
}

/* 路径规划搜索回调. */
- (void)onRouteSearchDone:(AMapRouteSearchBaseRequest *)request response:(AMapRouteSearchResponse *)response {
    
    if (response.route == nil) return;
   /// 解析response获取路径信息
}

/* 距离测量回调. */
- (void)onDistanceSearchDone:(AMapDistanceSearchRequest *)request response:(AMapDistanceSearchResponse *)response {
    
}

/* 公交站点回调*/
- (void)onBusStopSearchDone:(AMapBusStopSearchRequest *)request response:(AMapBusStopSearchResponse *)response {
    
    if (response.busstops.count == 0) return;
    /// 解析response获取公交站点信息
}

/* 公交路线回调*/
- (void)onBusLineSearchDone:(AMapBusLineBaseSearchRequest *)request response:(AMapBusLineSearchResponse *)response {
    if (response.buslines.count == 0) return;
    /// 解析response获取公交线路信息
}

- (void)AMapSearchRequest:(id)request didFailWithError:(NSError *)error {
    
    NSLog(@"Error: %@", error);
//    self.flutterResult(@"未搜索到结果");
    self.flutterResult(FlutterMethodNotImplemented);
}

#pragma mark -- 懒加载

- (AMapSearchAPI *)searchAPI {
    if (!_searchAPI) {
        _searchAPI = [[AMapSearchAPI alloc] init];
        _searchAPI.delegate = self;
    }
    return _searchAPI;
}

- (HQMapTools *)mapTools {
    if (!_mapTools) {
        _mapTools = [HQMapTools shareInstance];
    }
    return _mapTools;
}


@end
